var opc = 0;
var c;
var lastop;
var dbtile;
var enterpress = false;

    /*init: function () {
    cpu.init();
    mmu.init();
    gpu.init();
    timer.init();
    key.init();
    },*/
    function reset() {
        cpu.reset();
        mmu.reset();
        gpu.reset();
        timer.reset();
        cpu._r.pc = 0x100; mmu._inbios = 0; cpu._r.sp = 0xFFFE; cpu._r.hl = 0x014D; cpu._r.c = 0x13; cpu._r.e = 0xD8; cpu._r.a = 1;
        mmu.load("mario.gb");
    }

    function $(elm) {
        return document.getElementById(elm);
    }

    function debug() {
        $("opcount").innerHTML = opc;
        $("op").innerHTML = lastop.toString(16);
        $("cpua").innerHTML = cpu._r.a.toString(16);
        $("cpub").innerHTML = cpu._r.b.toString(16);
        $("cpuc").innerHTML = cpu._r.c.toString(16);
        $("cpud").innerHTML = cpu._r.d.toString(16);
        $("cpue").innerHTML = cpu._r.e.toString(16);
        $("cpuh").innerHTML = cpu._r.h.toString(16);
        $("cpul").innerHTML = cpu._r.l.toString(16);
        $("cpupc").innerHTML = cpu._r.pc.toString(16);
        $("cpusp").innerHTML = cpu._r.sp.toString(16);
        $("cpuime").innerHTML = cpu._r.ime;
        $("cput").innerHTML = cpu._r.t / 4;
        //$("cpuflag").innerHTML = cpu._r.fh.toString(16);
        $("cpufz").innerHTML = cpu._r.fz;
        $("cpufc").innerHTML = cpu._r.fc;

        $("curline").innerHTML = gpu._curline;
        $("modeclock").innerHTML = gpu._modeclocks / 4;
        $("linemode").innerHTML = gpu._linemode;
        $("yscrl").innerHTML = gpu._yscrl;
        $("xscrl").innerHTML = gpu._xscrl;

        $("div").innerHTML = timer._div;
        $("tima").innerHTML = timer._tima;
        $("tma").innerHTML = timer._tma;
        $("tac").innerHTML = timer._tac;
        $("if").innerHTML = mmu._if;
        $("ie").innerHTML = mmu._ie;
        $("mainclock").innerHTML = timer._clock.main;
        $("subclock").innerHTML = timer._clock.sub;
    }
    function start() {
        var fclock = cpu._clock.m + 17556;
        do {
            if (!cpu._halt) {
                //pcstack.push(cpu._r.pc);
                var op = mmu.rb(cpu._r.pc++);
                //opstack.push(op);
                lastop = op;
                cpu.ops[op]();
                opc++;
                cpu._r.pc &= 65535;
            }
            else cpu._r.t = 4;

            if (cpu._r.ime && mmu._ie && mmu._if) {
                cpu._r.ime = 0;
                cpu._halt = 0;
                var ifired = mmu._ie & mmu._if;
                cpu._r.ime = cpu._r._halt = 0;

                //cpu._r.t = 12; //32
                if (ifired & 0x01) {
                    mmu._if &= 0xfe;
                    cpu._r.sp -= 2;
                    mmu.ww(cpu._r.sp, cpu._r.pc);
                    cpu._r.pc = 0x40;
                    cpu._r.t = 12;
                }
                else if (ifired & 0x02) {
                    mmu._if &= 0xfd;
                    cpu._r.sp -= 2;
                    mmu.ww(cpu._r.sp, cpu._r.pc);
                    cpu._r.pc = 0x48;
                    cpu._r.t = 12;
                }
                else if (ifired & 0x04) {
                    mmu._if &= 0xfb;
                    cpu._r.sp -= 2;
                    mmu.ww(cpu._r.sp, cpu._r.pc);
                    cpu._r.pc = 0x50;
                    cpu._r.t = 12;
                }
                else if (ifired & 0x08) {
                    mmu._if &= 0xf7;
                    cpu._r.sp -= 2;
                    mmu.ww(cpu._r.sp, cpu._r.pc);
                    cpu._r.pc = 0x58;
                    cpu._r.t = 12;
                }
                else if (ifired & 0x16) {
                    mmu._if &= 0xef;
                    cpu._r.sp -= 2;
                    mmu.ww(cpu._r.sp, cpu._r.pc);
                    cpu._r.pc = 0x60;
                    cpu._r.t = 12;
                }
                else cpu._r.ime = 1;
            }
            cpu._clock.m += cpu._r.t / 4;
            cpu._clock.t += cpu._r.t;
            gpu.step();
            timer.run();

            if (enterpress && opc == c) {
                cpu._stop = 1;
            }
            if (cpu._stop) {
                clearInterval(runner);
                debug(document.getElementById("debug"));
                break;
            }

        } while (cpu._clock.m < fclock);
    }

    function CapStack() {
        this._pc = [];
        this._capacity = 5;
        this._count = 0;
    }
    CapStack.prototype.push = function (pc) {
        this._pc.push(pc);
        this._count++;
        if(this._count > this._capacity)
            this._pc.unshift(pc);
    }
    CapStack.prototype.getRes = function () {
        return this._pc;
    }
    var pcstack = new CapStack();
    var opstack = new CapStack();
